package util;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.imageio.ImageIO;

import pojo.MissionRelations;

/**
 * @author liusiyang
 * 
 */
public class TestImag {
	

	public static BufferedImage dopaint(Map<String, String> missionRelationmap,List<MissionRelations> missionRelations,Map<String, String> pmStatus) {
		
		HashMap<String, Location> NodeMap = new HashMap<String, Location>();
		HashMap<String, String> CompletedMap = new HashMap<String, String>();
		ArrayList<Edge> NodeList = new ArrayList<Edge>();
		if(missionRelationmap.isEmpty()||missionRelations.isEmpty()||pmStatus.isEmpty()){
			return null;
		}
		for(String key : missionRelationmap.keySet()){
			System.out.println("missionRelationmap的key有"+key);
			if(!"-1".equals(key))
			NodeMap.put(key,new Location(0,0,0));
		}
		for(String key : pmStatus.keySet()){
			CompletedMap.put(key,pmStatus.get(key));
		}
		
		for(String key : NodeMap.keySet()){
			System.out.println("NodeMap的key有"+key);
		}
		
		for(int i = 0 ; i < missionRelations.size() ; i++) {
			System.out.println("NodeList前置"+missionRelations.get(i).getFrontMissionName()+"NodeList后置："+missionRelations.get(i).getAfterMissionName());
			NodeList.add(new Edge(missionRelations.get(i).getFrontMissionName(),missionRelations.get(i).getAfterMissionName()));
			}
		Edge start = new Edge();
		Edge end = new Edge();
		//找出起始节点和终止节点
		for(Edge e:NodeList)
		{
			if("-1".equals(e.front))
			{
				start.front = e.front;
				start.after = e.after;
			}
			if("-2".equals(e.after))
			{
				end.front = e.front;
				end.after = e.after;
			}
		}
		
		ArrayList<Edge> OrderList = new ArrayList<Edge>(); //遍历完成后，正确排序的表
		ArrayList<Edge> NowList = new ArrayList<Edge>();  //当前层
		NowList.add(start);
		ArrayList<Edge> NextList = new ArrayList<Edge>(); //下一层
		int x = 1;
		int y = 1;
		int ymax = 0;
		int xmax = 0;
		Boolean flag = false;  //跨层标志
		while(true)
		{
			if(NextList.size() == 1 && NextList.get(0).equals(end))
				break;
			NextList.clear();
			for(Edge e:NowList)
			{
				if(NodeMap.containsKey(e.after))
					NodeMap.get(e.after).setWidth(x);
				for(Edge f:NodeList)
				{
					if(e.after.equals(f.front))
					{
						
						if(!(NextList.contains(f)))
						{
							NextList.add(f);
						}
					}
				}
			}
			if( NextList.size()>1 && NextList.contains(end))
				flag = true;
			if(!(NowList.get(0).front.equals("-1")))
			{
				for(Edge e:NowList)
				{
					if(NodeMap.containsKey(e.after))
						OrderList.add(e);
				}
			}
			NowList.clear();  //清空当前层
			NowList.addAll(NextList);  //将NextList层中所有数据放在NowList中
			x++;
		}
		xmax = x-1;
		NowList.clear();
		NowList.add(start);
		NextList.clear();
		HashMap<String,Location> VirtualPoint = new HashMap<String,Location>();
		ArrayList<Edge> FinalOrder = new ArrayList<Edge>();
		FinalOrder.add(start);
		Integer Virtual = -3;
		//重新遍历关系表，处理跨层问题
	
		//如果有跨层关系则加入虚拟节点
		if(flag == true)
		{
			for(Edge e:OrderList)
			{
				int distance = NodeMap.get(e.after).getWidth() - NodeMap.get(e.front).getWidth();
				int layer = NodeMap.get(e.front).getWidth();
				if(distance == 1)
					FinalOrder.add(e);
				else
				{
					//对跨层的前置节点处理
					Edge VirtualEdge1 = new Edge();
					VirtualEdge1.setFront(e.getFront());
					VirtualEdge1.setAfter(Virtual.toString());
					FinalOrder.add(VirtualEdge1);
					VirtualPoint.put(Virtual.toString(), new Location(++layer,0,0));
//					//跨层大于2的处理
					while(distance>2)
					{
						Edge VirtualEdge3 = new Edge();
						VirtualEdge3.setFront(Virtual.toString());
						Virtual = Virtual - 1;
						VirtualEdge3.setAfter(Virtual.toString());
						FinalOrder.add(VirtualEdge3);
						VirtualPoint.put(Virtual.toString(), new Location(++layer,0,0));
						distance -- ;
					}
					//对跨层的后置节点处理
					Edge VirtualEdge2 = new Edge();
					VirtualEdge2.setFront(Virtual.toString());
					VirtualEdge2.setAfter(e.getAfter());
					FinalOrder.add(VirtualEdge2);
					Virtual = Virtual - 1;
					
				
				} 
			}
			FinalOrder.add(end);
		}
		else
		{
			FinalOrder.addAll(OrderList);
			FinalOrder.add(end);
		}
		ymax = 0;
		//决定点的y和ymax
		while(true)
		{
			if(NextList.size() == 1 && NextList.get(0).equals(end))
				break;
			y = 1;
			NextList.clear();
			for(Edge e:NowList)
			{
				for(Edge f:FinalOrder)
				{
					if(e.after.equals(f.front))
					{
						if(!(NextList.contains(f)))
						{
							NextList.add(f);
						}
					}
				}
			}
			for(Edge e:NowList)
			{
				if(NodeMap.containsKey(e.after))
				{
					if(NodeMap.get(e.after).getHeight()==0)
					{
						NodeMap.get(e.after).setHeight(y);
						y++;
					}
				}
				if(VirtualPoint.containsKey(e.after))
				{
					if(VirtualPoint.get(e.after).getHeight()==0)
					{
						VirtualPoint.get(e.after).setHeight(y);
						y++;
					}
				}
			}
			y = y - 1;
			if(y>ymax) ymax = y;
			for(Edge e:NowList)
			{
				if(NodeMap.containsKey(e.after))
					NodeMap.get(e.after).setMaxheight(y);
				if(VirtualPoint.containsKey(e.after))
				{
					VirtualPoint.get(e.after).setMaxheight(y);;
				}
			}
			NowList.clear();  //清空当前层
			NowList.addAll(NextList);  //将NextList层中所有数据放在NowList中
		}
		
		
		
		//画图
		//先画出所有节点，然后在连线，将每个节点的前连接和后连接点记住
		int xstep = 75;  //每层之间的距离
		int ystep = 50;  //最高的那层节点之间的高度
		int rectheight = 40; //矩形框的高度 
		int rectwidth = 20;  //空白矩形框的宽度
		int maxheight = (ymax - 1) * ystep + ymax * rectheight; //整个图像的高度
		int maxhigh = maxheight + 50;
		int length = 0;
		int maxwidth = 0;
		int[] stringnumber = new int[xmax];
		for (Entry<String, Location> entry : NodeMap.entrySet())
        {   
			String s1 = entry.getKey();
            length = s1.length();
            if(stringnumber[entry.getValue().width-1]<length)
	        	stringnumber[entry.getValue().width-1] = length;
             
        }
		int stringlength = 0;
		for(int e:stringnumber)
			stringlength += e;
		maxwidth = xmax*xstep + ( xmax+2 ) * rectwidth+stringlength*32;
		BufferedImage image = new BufferedImage(maxwidth,maxhigh,BufferedImage.TYPE_INT_RGB);  
	    Graphics2D graphics = (Graphics2D)image.getGraphics();
	    graphics.setColor(Color.white);
	    graphics.fillRect(0, 0, maxwidth,maxhigh); 
		HashMap<String,ConnectPoint> ConMap = new HashMap<String,ConnectPoint>();
		int[] stringwidth = new int[xmax];
		for(int e:stringwidth)
			e = 0;
		graphics.setColor(Color.BLACK); 
		
		
		//遍历得到每层最大字符长度
		for (Entry<String, Location> entry : NodeMap.entrySet())
		{
			String s1 = entry.getKey();
			Font font = new Font("宋体", Font.BOLD, 30);
	        graphics.setFont(font);
	        FontMetrics fm = graphics.getFontMetrics(font);
	        int height = fm.getHeight();
	        int width = fm.stringWidth(s1);//获取字符串的长度 ，返回值是图片上的长度
	        if(stringwidth[entry.getValue().width-1]<width)
	        	stringwidth[entry.getValue().width-1] = width;
		}
		
		
		for (Entry<String, Location> entry : NodeMap.entrySet())
		{
			int yspace = 0;
			String s1 = entry.getKey();
			Font font = new Font("宋体", Font.BOLD, 30);
			graphics.setFont(font);
	        FontMetrics fm = graphics.getFontMetrics(font);
	        int height = fm.getHeight();
	        int width = fm.stringWidth(s1);//获取字符串的长度 ，返回值是图片上的长度
	        int mh = entry.getValue().maxheight;
	        if(ymax>1)
	        {
		        if(mh < ymax)
		        {
		        	yspace = (maxheight - mh * rectheight)/(mh+1);
		        }
		        else
		        	yspace = (maxheight - ymax * rectheight)/(mh-1);
	        }
	        else
	        	yspace = 0;
	        int xlocation = entry.getValue().width * xstep + (entry.getValue().width-1)*rectwidth;
	        int ylocation = 0 ;
	        if(mh < ymax)
	        	ylocation = yspace*entry.getValue().height + (entry.getValue().height -1) * rectheight+25;
	        else
	        	ylocation = yspace*(entry.getValue().height-1) + (entry.getValue().height -1) * rectheight+25;
	        for(int j = 0;j<entry.getValue().width-1;j++)
	        {
	        	xlocation += stringwidth[j];
	        }
//	        if(stringwidth[entry.getValue().width-1]<width)
//	        	stringwidth[entry.getValue().width-1] = width;
	        graphics.drawRect(xlocation, ylocation, rectwidth+width, rectheight);
	        if(CompletedMap.containsKey(s1))
	        {
	        	if("1".equals(CompletedMap.get(s1)))
	        	{
	        		graphics.setColor(Color.RED); 
	        		graphics.drawString(s1, xlocation+10, ylocation+rectheight-10);
	        		graphics.setColor(Color.BLACK);
	        	}
	        	else
	        		graphics.drawString(s1, xlocation+10, ylocation+rectheight-10);
	        }
	        
	        PointLocation frontpoint = new PointLocation(xlocation,ylocation+(int)(rectheight/2));
	        PointLocation afterpoint = new PointLocation(xlocation+width+rectwidth,ylocation+(int)(rectheight/2));
	        ConnectPoint connectpoint = new ConnectPoint(frontpoint,afterpoint);
	        ConMap.put(s1,connectpoint);
		}
		for (Entry<String, Location> entry :VirtualPoint.entrySet())
		{
			int yspace = 0;
			String s1 = entry.getKey();
//			Font font = new Font("宋体", Font.BOLD, 30);
//			graphics.setFont(font);
//	        FontMetrics fm = graphics.getFontMetrics(font);
//	        int height = fm.getHeight();
//	        int width = fm.stringWidth(s1);//获取字符串的长度 ，返回值是图片上的长度
	        int mh = entry.getValue().maxheight;
	        if(ymax>1)
	        {
		        if(mh < ymax)
		        {
		        	yspace = (maxheight - mh * rectheight)/(mh+1);
		        }
		        else
		        	yspace = (maxheight - ymax * rectheight)/(mh-1);
	        }
	        else
	        	yspace = 0;
	        int xlocation = entry.getValue().width * xstep + (entry.getValue().width-1)*rectwidth;
	        int ylocation = 0 ;
	        if(mh < ymax)
	        	ylocation = yspace*entry.getValue().height + (entry.getValue().height -1) * rectheight+25;
	        else
	        	ylocation = yspace*(entry.getValue().height-1) + (entry.getValue().height -1) * rectheight+25;
	        for(int j = 0;j<entry.getValue().width-1;j++)
	        {
	        	xlocation += stringwidth[j];
	        }
//			        if(stringwidth[entry.getValue().width-1]<width)
//			        	stringwidth[entry.getValue().width-1] = width;
	        PointLocation frontpoint = new PointLocation(xlocation,ylocation+(int)(rectheight/2));
	        PointLocation afterpoint = new PointLocation(xlocation+stringwidth[entry.getValue().width-1]+rectwidth,ylocation+(int)(rectheight/2));
	        ConnectPoint connectpoint = new ConnectPoint(frontpoint,afterpoint);
	        ConMap.put(s1,connectpoint);
		}
		FinalOrder.remove(start);
		FinalOrder.remove(end);
		int xstart = 0;
		int ystart = 0;
		int xend = 0; 
		int yend = 0;
		Graphics2D g2=(Graphics2D) graphics; 
	    g2.setPaint(Color.black);
		for(Edge e:FinalOrder)
		{
			if(NodeMap.containsKey(e.after))
			{
				xstart = ConMap.get(e.front).AfterPoint.x;
				ystart = ConMap.get(e.front).AfterPoint.y;
				xend = ConMap.get(e.after).FrontPoint.x;
				yend = ConMap.get(e.after).FrontPoint.y;
				drawAL(xstart, ystart, xend-5, yend, g2);
			}
			if(VirtualPoint.containsKey(e.after))
			{
				xstart = ConMap.get(e.front).AfterPoint.x;
				ystart = ConMap.get(e.front).AfterPoint.y;
				xend = ConMap.get(e.after).FrontPoint.x;
				yend = ConMap.get(e.after).FrontPoint.y;
				graphics.drawLine(xstart, ystart, xend, yend);
				xstart = ConMap.get(e.after).FrontPoint.x;
				ystart = ConMap.get(e.after).FrontPoint.y;
				xend = ConMap.get(e.after).AfterPoint.x;
				yend = ConMap.get(e.after).AfterPoint.y;
				graphics.setColor(Color.BLACK); 
				graphics.drawLine(xstart, ystart, xend, yend);
			}
			
		    
		}	
		graphics.dispose();//释放此图形的上下文并释放它所使用的所有系统资源  
	    
//		 File file2 =new File("F:/GitHub/PaintTest/PaintTest00/src/Submit/hello/");            //此目录保存缩小后的关键图
//         if(file2.exists()){
//              System.out.println("多级目录已经存在不需要创建！！");
//         }else{
//           //如果要创建的多级目录不存在才需要创建。
//            file2.mkdirs();
//          }
//		 File file2 =new File("F:/GitHub/PaintTest/PaintTest00/src/Submit/hello/");            //此目录保存缩小后的关键图
//      if(file2.exists()){
//           System.out.println("多级目录已经存在不需要创建！！");
//      }else{
//        //如果要创建的多级目录不存在才需要创建。
//         file2.mkdirs();
//       }
//      String name = "name";
      try {
		ImageIO.write(image, "jpg", new File("F:/name.jpg"));
	} catch (IOException e1) {
		// TODO Auto-generated catch block
		e1.printStackTrace();
	}
	
      System.out.println("Successful!!!");
	    //return image ;
		return image;
	}
	
	public static void drawAL(int sx, int sy, int ex, int ey,Graphics2D g2)

	{

         double  H  =   6 ;  // 箭头高度   
         double  L  =   6 ; // 底边的一半  
         int  x3  =   0 ;
         int  y3  =   0 ;
         int  x4  =   0 ;
         int  y4  =   0 ;
         double  awrad  =  Math.atan(L  /  H);  // 箭头角度   
         double  arraow_len  =  Math.sqrt(L  *  L  +  H  *  H); // 箭头的长度   
         double [] arrXY_1  =  rotateVec(ex  -  sx, ey  -  sy, awrad,  true , arraow_len);
         double [] arrXY_2  =  rotateVec(ex  -  sx, ey  -  sy,  - awrad,  true , arraow_len);
         double  x_3  =  ex  -  arrXY_1[ 0 ];  // (x3,y3)是第一端点   
         double  y_3  =  ey  -  arrXY_1[ 1 ];
         double  x_4  =  ex  -  arrXY_2[ 0 ]; // (x4,y4)是第二端点   
         double  y_4  =  ey  -  arrXY_2[ 1 ];

	     Double X3  =   new  Double(x_3);
	     x3  =  X3.intValue();
	     Double Y3  =   new  Double(y_3);
	     y3  =  Y3.intValue();
	     Double X4  =   new  Double(x_4);
	     x4  =  X4.intValue();
	     Double Y4  =   new  Double(y_4);
	     y4  =  Y4.intValue();
	     // g.setColor(SWT.COLOR_WHITE);
	     // 画线
	     g2.drawLine(sx, sy, ex, ey);
	     // 画箭头的一半
	     g2.drawLine(ex, ey, x3, y3);
	     // 画箭头的另一半
	     g2.drawLine(ex, ey, x4, y4);
	     }

	 


	    //计算
	    public  static double [] rotateVec( int  px,  int  py,  double  ang,  boolean  isChLen,
	            double  newLen)   
	    {
	        double  mathstr[]  =   new   double [ 2 ];
	        // 矢量旋转函数，参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度   
	        double  vx  =  px  *  Math.cos(ang)  -  py  *  Math.sin(ang);
	        double  vy  =  px  *  Math.sin(ang)  +  py  *  Math.cos(ang);
	        if  (isChLen)   {
	           double  d  =  Math.sqrt(vx  *  vx  +  vy  *  vy);
	           vx  =  vx  /  d  *  newLen;
	           vy  =  vy  /  d  *  newLen;
	           mathstr[ 0 ]  =  vx;
	           mathstr[ 1 ]  =  vy;
	       }
	        return  mathstr;
	   } 
}

class PointLocation
{
	int x;
	int y;
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	public PointLocation(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
}
class ConnectPoint
{
	PointLocation FrontPoint; //
	PointLocation AfterPoint;
	public PointLocation getFrontPoint() {
		return FrontPoint;
	}
	public void setFrontPoint(PointLocation frontPoint) {
		FrontPoint = frontPoint;
	}
	public PointLocation getAfterPoint() {
		return AfterPoint;
	}
	public void setAfterPoint(PointLocation afterPoint) {
		AfterPoint = afterPoint;
	}
	public ConnectPoint(PointLocation frontPoint, PointLocation afterPoint) {
		super();
		FrontPoint = frontPoint;
		AfterPoint = afterPoint;
	}
	
}

class Location //位置类
{
	int width; //定义节点的x
	int height; //定义节点的y
	int maxheight; //定义同层节点的数量
	public int getWidth() {
		return width;
	}
	public void setWidth(int width) {
		this.width = width;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int height) {
		this.height = height;
	}
	public int getMaxheight() {
		return maxheight;
	}
	public void setMaxheight(int maxheight) {
		this.maxheight = maxheight;
	}
	public Location(int width, int height, int maxheight) {
		super();
		this.width = width;
		this.height = height;
		this.maxheight = maxheight;
	}
	
}

class Edge  //节点的前后置关系
{
	String front;
	String after;
	public String getFront() {
		return front;
	}
	public void setFront(String front) {
		this.front = front;
	}
	public String getAfter() {
		return after;
	}
	public void setAfter(String after) {
		this.after = after;
	}
	
	public Edge() {
		super();
	}
	public Edge(String front, String after) {
		super();
		this.front = front;
		this.after = after;
	}
	public boolean equals(Object obj) {   
        if (obj instanceof Edge) {   
        	Edge e = (Edge) obj;   
            return this.front.equals(e.front)   
                    && this.after.equals(e.after);   
        }   
        return super.equals(obj);
	}
}


